iT邦幫忙

1

使用Bitbucket建立CI/CD

  • 分享至 

  • xImage
  •  

建立好CI/CD的流程,除了可以減少人工的操作之外,也能透過安排好的測試等排程來讓專案更加的穩定。現在也有不同的服務來幫助建立CI/CD流程,例如GitLab還有今天要介紹的bitbucket pipelines

在進入大綱以前,先說明想要建立的自動化部署流程

主機在main branch中透git push將程式碼push到bitbucket上
bitbucket根據設置的pipelines.yml,先建立虛擬環境進行程式碼的測試
測試通過後,使用SSH連接到遠端主機,進到專案目錄
根據專案目錄的docker配置刪除舊容器,建立新的容器完成部署
而這篇文章的重點會放在bitbucket想要使用SSH操作遠端主機時需要注意的地方,而不是yml本身,所以今天重點都在如何完成第一到第三步的過程

文章大綱

  1. 流程說明
  2. 實際操作流程
  • 遠端主機配置
  • Bitbucket配置
  1. 總結

流程說明

https://ithelp.ithome.com.tw/upload/images/20241226/20161866TBxHjhik6g.jpg

首先我們從上面的Linode部分(遠端主機)來看,因為需要操作專案、使用docker建立容器與操作git,所以我們需要建立具備相關權限的群組與用戶。雖然在操作docker時很常需要用到root用戶,但是建立一個具有操作docker權限的用戶才是更安全的做法,而建立群組的好處是能將先前具有操作專案權限的用戶納入群組中

為了要讓Bitbucket能使用用戶透過SSH連到遠端主機,需要在sshd_config檔案配置相關參數,以及將Bitbucket建立的公鑰放到遠端主機的authorized_keys檔案中

接著來看下圖關於Bitbucket的配置,因為需要讓遠端主機能夠操作git,所以要將遠端主機的public key放到Bitbucket的Access keys配置中。並且我們需要在Bitbucket中配置SSH密鑰(不論是自己生成,還是拿本機的來用都可以)。生產或是拿來的公鑰,如同上段說的要拿去遠端主機的authorized_keys檔案,而私鑰則是之後pipeline需要用在SSH登入時驗證

最後來提及Repository variables配置的部分,因為是使用ssh_run鏡像,所以需要配置SSH_USER與SERVER才能讓pipeline使用SSH登入。而SSH_KEY如果在前面的步驟已經配置在Bitbucket的設定中,這邊可以不用填。而其他你需要在專案中用到的環境變數,如果是已經在遠端主機的檔案配置中的話,這邊可以不用配置,我這邊配置的是要給測試階段時,此時環境是Bitbucket的獨立虛擬環境,不會有遠端主機配置好的環境變數,所以還是要補上。

以上簡單的介紹一下流程,如果覺得還有哪邊覺得不是很清楚的話,可以看完底下詳細的步驟後,再回來把整個流程梳理一次邏輯~

實際操作流程

遠端主機配置

  • 確認遠端主機是否有docker群組
getent group docker
# 如果有的話會顯示
docker:x:990:
  • 建立用戶並設置密碼(雖然之後是使用公鑰,但還是可以配置密碼)
useradd -m -s /bin/bash <username> #建立用戶
passwd <username> # 修改密碼
  • 給予用戶能使用docker的權限
usermod -aG docker <username>

用戶的部分配置好了,接著要建立群組
為什麼要建立群組?而不是直接把所有需要的權限丟到剛剛的用戶就好了?
因為遠端主機的專案資料,不是只有這個部署的用戶要使用,因此建立群組然後讓其有專案資料的權限,最後再將用戶們納入群組之下

  • 建立專門的群組
sudo groupadd <group_name>
  • 將用戶添加到群組,這邊除了剛剛建立的用戶,也要把之前建立專案的用戶納入
usermod -aG <group_name> <username>
  • 修改目錄的群組擁有權,同時配置讀取與執行權限,以及讓新建立的檔案自動繼承父目錄的群組
chown :<group_name> <file_path>
chmod g+rx <file_path>
chmod g+s <file_path>

這邊要注意:要從絕對路徑開始,直到專案目錄的每一層都要配置,並且要注意.git的隱藏資料夾有沒有套用到配置,沒有的話會部署失敗

接下來我們要確認新建立的用戶能夠使用SSH連線

sudo vim /etc/ssh/sshd_config

並且確認這些參數

PubkeyAuthentication yes # 表示能公鑰連線
PasswordAuthentication no # 不使用輸入密碼的方式登入
AllowUsers <user_name> # 確認能用ssh連線

最後來配置SSH密鑰認證時需要的檔案與權限

  • 建立.ssh目錄,並且配置權限,使擁有者有讀+寫+執行權限
mkdir -p /<root_path>/<username>/.ssh
chown <username>:<username> /<root_path>/<username>/.ssh
chmod 700 /<root_path>/<username>/.ssh
  • 在.ssh內建立authorized_keys檔案,儲存允許登入此用戶的公鑰
touch /<root_path>/<username>/.ssh/authorized_keys
chown <username>:<username> /<root_path>/<username>/.ssh/authorized_keys
chmod 600 /<root_path>/<username>/.ssh/authorized_keys

同時我們也在這裡建立密鑰,公鑰之後要給Bitbucket的Access keys來使用遠程倉庫(repository)的權限

ssh-keygen -t rsa -b 4096 -C ""

在遠端主機的工作就告一段落了,我們接著來配置Bitbucket

Bitbucket配置

先進到Repository settings中

https://ithelp.ithome.com.tw/upload/images/20241226/20161866Yab0NVXOyk.png

將剛剛的公鑰(id_rsa)放到Bitbucket中

https://ithelp.ithome.com.tw/upload/images/20241226/20161866kzuQ3W15k7.png

接著我們要來配置Repository settings中的SSH Keys

如果pipeline中需要使用多組SSH keys,那這邊可能可以跳過,直接全部配置在Repository variables上。但是我們就只有一組要認證,所以可以直接配置在這裡,後面的pipelines.yml可以省略一些步驟

https://ithelp.ithome.com.tw/upload/images/20241226/20161866MEbBnVzDzZ.png

我這邊因為有建立了所以長這樣,如果是第一次新增也會有按鈕讓你新增

不過輸入Private key時要注意,一定要連第一行跟最後一行都輸入進去

-----BEGIN OPENSSH PRIVATE KEY-----
xxxxxxxx
-----END OPENSSH PRIVATE KEY-----

然後用遠端主機的ip來建立know host
https://ithelp.ithome.com.tw/upload/images/20241226/201618664uflN8g7rG.png

最後就來配置Repository variables

https://ithelp.ithome.com.tw/upload/images/20241226/20161866BjVi404sJq.png

其中根據官方提供的ssh-run鏡像,SSH_USER跟SERVER是必須,其他的變數就根據自己需求來添加

至於pipelines.yml本身大致上的架構如下,畢竟今天重點不是在他身上,就不多做贅述,讀者再根據自己需求做調整

pipelines:
  default:
    - step:
        name: Test
        image: python:3.12-slim
        caches:
          - pip
        script:
          - apt-get update && apt-get install -y gcc python3-dev
          # 這裡是相對於 repo root
          - pip install -r <root_path>/requirements.txt
          - cd <file_path>
          - pytest -v

    - step:
        name: Deploy to Production
        deployment: production
        script:
          - pipe: atlassian/ssh-run:0.8.1
            variables:
              SSH_USER: $SSH_USER
              SERVER: $SERVER
              COMMAND: >
                set -e;
                echo "當前用戶信息:" && whoami && groups;

                echo "開始嘗試進入目錄:" &&
                cd <file_path> &&
                echo "成功進入目標目錄" &&
                pwd &&

                echo "開始執行部署步驟" &&
                docker-compose ps > previous_state.txt &&
                git pull origin main &&

                docker-compose --env-file ../.env down &&
                docker-compose --env-file ../.env build &&
                docker-compose --env-file ../.env up -d &&

                if ! docker-compose ps | grep -q "web.*Up"; then
                  echo "部署失敗,正在回滾..." &&
                  docker-compose down &&
                  cat previous_state.txt &&
                  exit 1;
                fi &&
                docker system prune -f --volumes &&
                echo "部署完成!"

definitions:
  services:
    docker:
      memory: 256

總結

這是我第一次建立的CI/CD流程,中間失敗了50次以上,主要都是卡在對于權限的配置與SSH中遠端主機與Bitbucket所扮演的角色定位不夠了解,以及第一次寫COMMAND,不知道要用&&而是傻傻用;

整個流程大致上如下:

  • 配置遠端主機的用戶與群組之相關權限
  • 使該用戶能用SSH連線
  • Bitbucket上配置SSH密鑰用於SSH連線與配置變數來進行SSH登入

雖然文中是使用Bitbucket,但是了解了相關流程後,使用其他服務也是能照著相同的邏輯去處理~

參考資料

https://support.atlassian.com/bitbucket-cloud/docs/set-up-pipelines-ssh-keys-on-linux/
https://support.atlassian.com/bitbucket-cloud/docs/configure-ssh-and-two-step-verification/
https://bitbucket.org/atlassian/ssh-run/src/master/?source=post_page
https://dev.to/manuelbosi/bitbucket-pipelines-configure-ssh-keys-1l56?source=post_page


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言